﻿using SXICE.Core.Models;
using System;
using System.Collections.Generic;
using System.Linq;

namespace SXICE.Core.Helpers
{
    /// <summary>
    /// 帮助扩展类
    /// </summary>
    public static class HelperExtentions
    {
        /// <summary>
        /// 是否为null或空
        /// </summary>
        /// <param name="source">要检查的对象</param>
        /// <returns>结果</returns>
        public static bool IsNullOrEmpty(this object source)
        {
            if (ReferenceEquals(null, source))
                return true;
            if (source is string)
                return string.IsNullOrWhiteSpace((string)source);
            return false;
        }

        #region 对象转换

        /// <summary>
        /// 获取枚举ID
        /// </summary>
        /// <param name="source">要获取ID的枚举</param>
        /// <returns>枚举ID</returns>
        public static int ToInt(this Enum source)
        {
            return Convert.ToInt32(source);
        }

        /// <summary>
        /// 对象转换为实体
        /// </summary>
        /// <typeparam name="T">要转换的实体类型</typeparam>
        /// <param name="source">源对象</param>
        /// <returns>转换后的对象</returns>
        public static T ToEntity<T>(this object source)
        {
            return (T)source;
        }

        /// <summary>
        /// 字符串转换为数字数组
        /// </summary>
        /// <param name="source">源字符串</param>
        /// <param name="seprator">分隔符</param>
        /// <returns>结果</returns>
        public static int[] ToIntArray(this string source, char seprator = ',')
        {
            if (source.IsNullOrEmpty())
                return new int[0];
            return source.SplitNoEmpty(seprator).Select(c => { int.TryParse(c, out var result); return result; }).ToArray();
        }

        #endregion

        #region 返回结果

        /// <summary>
        /// 转换为异常结果
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="ex">异常</param>
        /// <returns>结果</returns>
        public static ReturnResult<T> ToExceptionResult<T>(this Exception ex)
        {
            return ErrorCode.INNER_EXCEPTION.ToResult<T>(ex.Message);
        }

        /// <summary>
        /// 转换为异常结果
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="ex">异常</param>
        /// <returns>结果</returns>
        public static ReturnResult ToExceptionResult(this Exception ex)
        {
            return ErrorCode.INNER_EXCEPTION.ToResult(ex.Message);
        }

        /// <summary>
        /// 转换为分页异常结果
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="ex">异常</param>
        /// <returns>结果</returns>
        public static ReturnPageListResult<T> ToExceptionPageResult<T>(this Exception ex)
        {
            return ErrorCode.INNER_EXCEPTION.ToPageResult<T>(ex.Message);
        }

        /// <summary>
        /// 转换为Result
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="errorCode">错误码</param>
        /// <param name="errorMessage">错误消息</param>
        /// <returns>结果</returns>
        public static ReturnResult<T> ToResult<T>(this Enum errorCode, string errorMessage)
        {
            return ReturnResult<T>.GetResult(errorCode.ToInt(), errorMessage);
        }

        /// <summary>
        /// 将对象转换为Result
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="source">源目标</param>
        /// <returns>结果</returns>
        public static ReturnResult<T> ToResult<T>(this T source)
        {
            return ReturnResult<T>.GetResult(source);
        }

        /// <summary>
        /// 将对象转换为Result
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="errorCode">源目标</param>
        /// <param name="errorMessage">错误信息</param>
        /// <returns>结果</returns>
        public static ReturnResult ToResult(this Enum errorCode, string errorMessage)
        {
            return ReturnResult.GetResult(errorCode.ToInt(), errorMessage);
        }

        /// <summary>
        /// 将对象转换为Result
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="source">源数据</param>
        /// <param name="total">总数</param>
        /// <returns>结果</returns>
        public static ReturnPageListResult<T> ToResult<T>(this List<T> source, int total)
        {
            return ReturnPageListResult<T>.GetResult(source, total);
        }

        /// <summary>
        /// 将ReturnResult转换为错误的Result
        /// </summary>
        /// <typeparam name="V">要转换的类型</typeparam>
        /// <param name="source">源目标</param>
        /// <returns>结果</returns>
        public static ReturnResult<V> ToErrorResult<V>(this ReturnResult source)
        {
            return ReturnResult<V>.GetResult(source.ErrorCode, source.ErrorMessage);
        }

        /// <summary>
        /// 将ReturnResult转换为分页错误的Result
        /// </summary>
        /// <typeparam name="V">要转换的类型</typeparam>
        /// <param name="source">源Result</param>
        /// <returns></returns>
        public static ReturnPageListResult<V> ToErrorPageResult<V>(this ReturnResult source)
        {
            return ReturnPageListResult<V>.GetResult(source.ErrorCode, source.ErrorMessage);
        }

        /// <summary>
        /// 转换为Result或者错误结果
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="V"></typeparam>
        /// <param name="source">源目标</param>
        /// <param name="func">Func</param>
        /// <returns>结果</returns>
        public static ReturnResult<V> ToResultOrError<T, V>(this ReturnResult<T> source, Func<T, V> func)
        {
            if (source.Success)
                return ReturnResult<V>.GetResult(func(source.Result));
            return ReturnResult<V>.GetResult(source.ErrorCode, source.ErrorMessage);
        }

        /// <summary>
        /// 将数字转为错误码
        /// </summary>
        /// <typeparam name="T">类型</typeparam>
        /// <param name="errorCode">错误码</param>
        /// <param name="errorMessage">错误消息</param>
        /// <returns>结果</returns>
        public static ReturnResult<T> ToIntErrorResult<T>(this int errorCode, string errorMessage)
        {
            return ReturnResult<T>.GetResult(errorCode, errorMessage);
        }

        /// <summary>
        /// 将数字转为错误码
        /// </summary>
        /// <typeparam name="T">类型</typeparam>
        /// <param name="errorCode">错误码</param>
        /// <param name="errorMessage">错误消息</param>
        /// <returns>结果</returns>
        public static ReturnResult ToIntErrorResult(this int errorCode, string errorMessage)
        {
            return ReturnResult.GetResult(errorCode, errorMessage);
        }

        /// <summary>
        /// 转换为分页Result
        /// </summary>
        /// <typeparam name="T">类型</typeparam>
        /// <param name="errorCode">错误码</param>
        /// <param name="errorMessage">错误消息</param>
        /// <returns>结果</returns>
        public static ReturnPageListResult<T> ToPageResult<T>(this Enum errorCode, string errorMessage)
        {
            return ReturnPageListResult<T>.GetResult(errorCode.ToInt(), errorMessage);
        }

        #endregion

        #region 验证

        /// <summary>
        /// 验证规则
        /// </summary>
        /// <param name="rule">要验证的规则</param>
        /// <param name="parameters">参数</param>
        /// <returns>结果</returns>
        public static bool ValidateRule(this object rule, IDictionary<string, object> parameters)
        {
            if (rule.IsNullOrEmpty())
                return true;
            var nRule = rule.ToString();
            if (null != parameters)
                foreach (var param in parameters)
                    nRule = nRule?.Replace(param.Key, param.Value.ToString());
            return DyncmicRuntime.Compute(nRule);
        }

        /// <summary>
        /// 验证规则
        /// </summary>
        /// <param name="rule">要验证的规则</param>
        /// <param name="idNumber">身份证号</param>
        /// <returns>结果</returns>
        public static bool ValidateRule(this object rule, string idNumber)
        {
            return rule.ValidateRule(CommonHelper.GetAgeFromIDNumber(idNumber) ?? 0, CommonHelper.GetSex(idNumber));
        }

        /// <summary>
        /// 验证规则
        /// </summary>
        /// <param name="rule">要验证的规则</param>
        /// <param name="sex">性别</param>
        /// <param name="age">年龄</param>
        /// <returns>结果</returns>
        public static bool ValidateRule(this object rule, int age = 0, string sex = null)
        {
            if (rule.IsNullOrEmpty())
                return true;
            var nRule = rule.ToString()?.Replace("sex", sex)?.Replace("age", age.ToString());
            return DyncmicRuntime.Compute(nRule);
        }

        #endregion

        #region 字符串

        /// <summary>
        /// 拼接字符串
        /// </summary>
        /// <param name="source">源数据</param>
        /// <param name="separator">拼接词</param>
        /// <returns>结果</returns>
        public static string JoinS<T>(this IEnumerable<T> source, string separator = ",")
        {
            return string.Join(separator, source);
        }

        /// <summary>
        /// 格式化
        /// </summary>
        /// <param name="source">要格式化的字符串</param>
        /// <param name="parameters">参数</param>
        /// <returns>结果</returns>
        public static string Format(this string source, params object[] parameters)
        {
            return string.Format(source, parameters);
        }

        /// <summary>
        /// 分割成没有空格的字符串数组
        /// </summary>
        /// <param name="source">要分割的字符串</param>
        /// <param name="seprator">分隔符</param>
        /// <returns>结果</returns>
        public static string[] SplitNoEmpty(this string source, char seprator = ',')
        {
            return source?.Split(new char[] { seprator }, StringSplitOptions.RemoveEmptyEntries) ?? new string[0];
        }

        #endregion
    }
}
